import { useEffect, useState } from "react";
import { web3Accounts, web3Enable, web3FromAddress } from "@polkadot/extension-dapp";
import { ApiPromise, WsProvider } from "@polkadot/api";
import { Signer } from "@polkadot/api/types";

type UsePolkadotReturn = {
    isConnected: boolean;
    address: string | null;
    apiState: boolean;
    polkadotApi: ApiPromise | null;
    accounts: string[];
    transfer: (recipientAddress: string, amount: bigint) => Promise<void>;
    isPending: boolean;
    apiError: string | null;
    signer: Signer | undefined;
};

const usePolkadot = (): UsePolkadotReturn => {
    const [address, setAddress] = useState<string | null>(null);
    const [accounts, setAccounts] = useState<string[]>([]);
    const [polkadotApi, setPolkadotApi] = useState<ApiPromise | null>(null);
    const [isConnected, setIsConnected] = useState<boolean>(false);
    const [apiState, setApiState] = useState<boolean>(false);
    const [isPending, setIsPending] = useState<boolean>(false);
    const [apiError, setApiError] = useState<string | null>(null);
    const [signer, setSigner] = useState<Signer | undefined>(undefined);

    // 初始化账户和 API
    useEffect(() => {
        const initPolkadot = async () => {
            try {
                const allInjected = await web3Enable("my cool dapp");
                if (allInjected.length === 0) {
                    setApiError("No Polkadot extension found.");
                    return;
                }

                const allAccounts = await web3Accounts();
                if (allAccounts.length === 0) {
                    setApiError("No accounts available in the Polkadot extension.");
                    return;
                }

                const defaultAddress = allAccounts[0].address;
                setAccounts(allAccounts.map((account) => account.address));
                setAddress(defaultAddress);
                setIsConnected(true);

                const injector = await web3FromAddress(defaultAddress);
                setSigner(injector.signer);

                const api = await ApiPromise.create({
                    provider: new WsProvider("wss://rpc.polkadot.io"),
                });

                setPolkadotApi(api);
                setApiState(true);
            } catch (error) {
                setApiError("Initialization error, please try again.");
                console.error("Initialization error:", error);
            }
        };

        initPolkadot();
    }, []);

    // 通用的发送交易方法
    const sendTransaction = async (tx: any, address: string) => {
        return new Promise<void>((resolve) => {
            const unsub = tx.signAndSend(
                address,
                { signer },
                (result: any) => {
                    if (result.status.isFinalized) {
                        console.log(`Transaction finalized at block hash: ${result.status.asFinalized}`);
                        unsub();
                        resolve();
                    } else if (result.status.isInBlock) {
                        console.log(`Transaction in block: ${result.status.asInBlock}`);
                    } else {
                        console.log(`Transaction status: ${result.status}`);
                    }
                }
            );
        });
    };

    // 转账方法
    const transfer = async (recipientAddress: string, amount: bigint) => {
        if (!polkadotApi || !address) {
            console.warn("Polkadot API or sender address is not ready.");
            return;
        }

        setIsPending(true);
        try {
            const tx = polkadotApi.tx.balances.transferKeepAlive(recipientAddress, amount);
            await sendTransaction(tx, address);
        } catch (error) {
            console.error("Transfer error:", error);
            setApiError("Transfer failed, please try again.");
        } finally {
            setIsPending(false);
        }
    };

    return {
        isConnected,
        address,
        apiState,
        polkadotApi,
        accounts,
        transfer,
        isPending,
        apiError,
        signer
    };
};

export default usePolkadot;
